﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;

namespace Jiubang.Communication.Core {
    internal  class ThreadSafeCollection<T> : ICollection<T> {
        private List<T> _list;

        public ThreadSafeCollection(int capacity) {
            _list = new List<T>(capacity);
        }

        #region ICollection<T> Members

        public IEnumerator<T> GetEnumerator() {
            return _list.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator() {
            return ((IEnumerable)_list).GetEnumerator();
        }

        public void Add(T item) {
            List<T> orginal, current;
            do {
                orginal = _list;

                if (orginal.Contains(item)) {
                    throw new ArgumentException("不允许重复值");
                }

                current = new List<T>(orginal.Count + 1);
                current.AddRange(orginal);
                current.Add(item);
            } while (Interlocked.CompareExchange(ref _list, current, orginal) != orginal);
        }

        public void Clear() {
            ICollection<T> orginal;
            do {
                orginal = _list;
                if (orginal != null) 
                    orginal.Clear();
            } while (orginal != _list);
        }

        public bool Contains(T item) {
            return _list.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex) {
            _list.CopyTo(array, arrayIndex);
        }

        public bool Remove(T item) {
            List<T> orginal, current;
            bool removedItem;
            do {
                orginal = _list;
                current = new List<T>(orginal.Count);
                removedItem = false;
                foreach (T orginalItem in orginal) {
                    if (!orginalItem.Equals(item)) {
                        current.Add(orginalItem);
                        removedItem = true;
                    }
                }
            } while (Interlocked.CompareExchange(ref _list, current, orginal) != orginal);
            return removedItem;
        }

        public int Count { get { return _list.Count; } }

        public bool IsReadOnly { get { return false; } }

        #endregion
    }
}